/*
 * 著作权声明
 * Copyright (c) 2025.8 拾壹
 * 本代码为个人独立开发，未经本人书面许可，任何组织或个人不得擅自复制、修改、分发、用于商业用途。
 * 联系方式：sjw123521@qq.com
 */
 
package com.xmqsfsky1017.bzgzs;

import android.content.Context;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.HashMap;

public final class Room {
    private final String renterName;
    private final String roomNumber;
    private final BaauzougungNumber m3Water;
    private final BaauzougungNumber kwhZila;
    private final BaauzougungNumber rent;
    private final BaauzougungNumber waterUnitPrice;
    private final BaauzougungNumber zilaUnitPrice;
    private final BaauzougungNumber lastWater;
    private final BaauzougungNumber thisWater;
    private final BaauzougungNumber lastZila;
    private final BaauzougungNumber thisZila;
	private final String writer;

    private Room(Builder builder) {
        this.renterName = builder.name;
        this.roomNumber = builder.roomNumber;
        this.waterUnitPrice = builder.waterUnitPrice;
        this.zilaUnitPrice = builder.zilaUnitPrice;
        this.lastWater = builder.lastWater;
        this.thisWater = builder.thisWater;
        this.lastZila = builder.lastZila;
        this.thisZila = builder.thisZila;
        this.rent = builder.rent;
        this.m3Water = calculateUsage(lastWater, thisWater, "水表");
        this.kwhZila = calculateUsage(lastZila, thisZila, "电表");
		this.writer=builder.writer;
    }

    private BaauzougungNumber calculateUsage(BaauzougungNumber last, BaauzougungNumber current, String meterType) {
        if (last == null) throw new IllegalArgumentException(meterType + "上次抄表值未设置");
        if (current == null) throw new IllegalArgumentException(meterType + "本次抄表值未设置");
        BaauzougungNumber usage = current.subtract(last);
        if (usage.isNegative()) {
            throw new IllegalArgumentException(meterType + "本次抄表值不能小于上次抄表值");
        }
        return usage;
    }

    public String getReceipt(Context context) {
        Map<String, String> replacements = new HashMap<>();
        replacements.put("_RN_", renterName);
        replacements.put("_RNB_", roomNumber);
        replacements.put("_MTH_", "本月");
        replacements.put("_RNT_", rent.toString());
        replacements.put("_TW_", thisWater.toString());
        replacements.put("_LW_", lastWater.toString());
        replacements.put("_M3W_", m3Water.toString());
        replacements.put("_WUP_", waterUnitPrice.toString());
        replacements.put("_WM_", getWaterMoney().toString());
        replacements.put("_LZ_", lastZila.toString());
        replacements.put("_TZ_", thisZila.toString());
        replacements.put("_KWHZ_", kwhZila.toString());
        replacements.put("_ZUP_", zilaUnitPrice.toString());
        replacements.put("_ZM_", getZilaMoney().toString());
        replacements.put("_BR_", getTotalMoney().toBigWrite());
        replacements.put("_SR_", getTotalMoney().toString());
		replacements.put("_WTR_",getWriter().toString());

        String[] templates = new String[4];
        templates[0] = context.getString(R.string.receipt_template_1);
        templates[1] = context.getString(R.string.receipt_template_2);
        templates[2] = context.getString(R.string.receipt_template_3);
        templates[3] = context.getString(R.string.receipt_template_4);

        StringBuilder receipt = new StringBuilder();
        for (int i = 0; i < templates.length; i++) {
            String template = templates[i];
            for (Map.Entry<String, String> entry : replacements.entrySet()) {
                template = template.replace(entry.getKey(), entry.getValue());
            }
            receipt.append(template).append("\n");
        }
        return receipt.toString();
    }

    public String getRenterName() {
        return renterName;
    }

    public String getRoomNumber() {
        return roomNumber;
    }

    public BaauzougungNumber getM3Water() {
        return m3Water;
    }

    public BaauzougungNumber getKwhZila() {
        return kwhZila;
    }

    public BaauzougungNumber getRent() {
        return rent;
    }

    public BaauzougungNumber getWaterUnitPrice() {
        return waterUnitPrice;
    }

    public BaauzougungNumber getZilaUnitPrice() {
        return zilaUnitPrice;
    }

    public BaauzougungNumber getWaterMoney() {
        return m3Water.multiply(waterUnitPrice);
    }

    public BaauzougungNumber getZilaMoney() {
        return kwhZila.multiply(zilaUnitPrice);
    }

    public BaauzougungNumber getTotalMoney() {
        return getWaterMoney().add(getZilaMoney()).add(rent);
    }

    public BaauzougungNumber getLastWater() {
        return lastWater;
    }

    public BaauzougungNumber getThisWater() {
        return thisWater;
    }

    public BaauzougungNumber getLastZila() {
        return lastZila;
    }

    public BaauzougungNumber getThisZila() {
        return thisZila;
    }
	
	public String getWriter() {
		return writer;
	}

    public static class Builder {
        private final String name;
        private final String roomNumber;
        private BaauzougungNumber rent;
        private BaauzougungNumber lastWater;
        private BaauzougungNumber thisWater;
        private BaauzougungNumber lastZila;
        private BaauzougungNumber thisZila;
        private BaauzougungNumber waterUnitPrice;
        private BaauzougungNumber zilaUnitPrice;
		private String writer;

        public Builder(Context context, String name, String roomNumber,String writer) {
            this.name = name;
            this.roomNumber = roomNumber;
            this.waterUnitPrice = null;
            this.zilaUnitPrice = new BaauzougungNumber(context.getString(R.string.zila_unit_price));
            this.rent = null;
            this.lastWater = null;
            this.thisWater = null;
            this.lastZila = null;
            this.thisZila = null;
			this.writer = writer;
        }

        public Builder setWaterUnitPrice(BaauzougungNumber waterUnitPrice) {
            this.waterUnitPrice = waterUnitPrice;
            return this;
        }

        public Builder setZilaUnitPrice(BaauzougungNumber zilaUnitPrice) {
            this.zilaUnitPrice = zilaUnitPrice;
            return this;
        }

        public Builder setRent(BaauzougungNumber rent) {
            this.rent = rent;
            return this;
        }

        public Builder setLastWater(BaauzougungNumber lastWater) {
            this.lastWater = lastWater;
            return this;
        }

        public Builder setThisWater(BaauzougungNumber thisWater) {
            this.thisWater = thisWater;
            return this;
        }

        public Builder setLastZila(BaauzougungNumber lastZila) {
            this.lastZila = lastZila;
            return this;
        }

        public Builder setThisZila(BaauzougungNumber thisZila) {
            this.thisZila = thisZila;
            return this;
        }

		public boolean isCompleted() {
            try {
                for (Field field : this.getClass().getDeclaredFields()) {
                    field.setAccessible(true);
                    Object value = field.get(this);
                    if (value == null || (value instanceof String && ((String) value).isEmpty())) {
                        return false;
                    }
                }
                return true;
            } catch (IllegalAccessException e) {
                return false; // 反射失败直接返回false
            }
        }


        public Room build() {
			if (!this.isCompleted())throw new IllegalStateException("租户信息未完善");
            return new Room(this);
        }
    }
}
